package org.example.config;

/**
 * @author liyishan
 * @date 2024/1/10 14:48
 * @apiNote
 */

import lombok.extern.slf4j.Slf4j;
import org.example.aop.TimeStatisticsLimitAspect;
import org.example.properties.RateLimitProperties;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

/**
 * Redis普通时间统计限流自动装配配置类
 * @author Mr.Tao
 */
@ConditionalOnExpression("#{'true'.equals(environment['rate-limit.enabled']) and ('2'.equals(environment['rate-limit.type']) or '-1'.equals(environment['rate-limit.type']))}")
@Import({RateLimitProperties.class, RedisAutoConfig.class})
@Configuration
@Slf4j
public class TimeStatisticsLimitAutoConfig {
    @Autowired
    private RateLimitProperties limitProperties;

    @Autowired
    @Qualifier("limitRedisTemplate")
    private RedisTemplate<String, Long> redisTemplate;

    @Autowired
    @Qualifier("limitRedisLuaScript")
    private DefaultRedisScript<Long> redisLuaScript;

    @Bean(name = "timeStatisticsLimitPointCut")
    public Pointcut timeStatisticsLimitPointCut() {
        return limitProperties.getPointcutExpression(limitProperties.getStrategyConfig().getTimeStatisticsLimitPackagePath());
    }

    @Bean(name = "timeStatisticsLimitAspect")
    public TimeStatisticsLimitAspect timeStatisticsLimitAspect() {
        return new TimeStatisticsLimitAspect(redisTemplate, redisLuaScript, limitProperties);
    }
    /*
     * 自定义切面，可以灵活配置切点和切面。
     * @return 切面
     */
    @Bean(name = "timeStatisticsLimitDefaultPointcutAdvisor")
    public DefaultPointcutAdvisor timeStatisticsLimitDefaultPointcutAdvisor() {
        DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
        defaultPointcutAdvisor.setPointcut(timeStatisticsLimitPointCut());
        defaultPointcutAdvisor.setAdvice(timeStatisticsLimitAspect());
        log.info("基于Redis的普通时间统计限流配置加载成功，限流接口所在包路径为" + limitProperties.getLimitPath(limitProperties.getStrategyConfig().getTimeStatisticsLimitPackagePath()));
        return defaultPointcutAdvisor;
    }
}
